/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief Connection dispatcher module header.
 * \author Antti Maula <antti.maula@tkk.fi>
 */

#ifndef _CONNECTIONDISP_H_
#define _CONNECTIONDISP_H_

#include "protocol.h"
#include "connection.h"
#include "connectionUDP.h"
#include "connectionTCP.h"
#include "connectionUNIX.h"
#include "connectionList.h"
#include "connectiontypes.h"
#include "msgreplybuffer.h"
#include "idmap.h"
#include <sys/poll.h>
#include <netinet/in.h>

#define CONNECTIONDISP_ERROR                  -1
#define CONNECTIONDISP_OK                     0

#define CONNECTIONDISP_DEFAULT_MAX_PACKET     10000000

#define CD_FLAG_THREADACTIVE_STREAM_DATA                      1
#define CD_FLAG_THREADACTIVE_TCP_CONNECTOR                    2
#define CD_FLAG_THREADACTIVE_UDP_CONNECTOR                    4
#define CD_FLAG_THREADACTIVE_UNIX_CONNECTOR                   8

#define CD_THREADHANDLE_STREAM_DATA           0
#define CD_THREADHANDLE_TCP_CONNECTOR         1
#define CD_THREADHANDLE_UDP_CONNECTOR         2
#define CD_THREADHANDLE_UNIX_CONNECTOR        3

#define CD_THREADHANDLE_COUNT                 4

/** Structure containing information for dispatching data and
 * connections.
 */
typedef struct _connectionDisp
{
  TServers servers;                   ///< Server side information.
  TClients clients;                   ///< 
  TConnectionList *connectionListPtr; ///< Connection list.

  int disconnectedClientSocketsCount;  ///< How may clients sockets unconnected?

  int maxAllowedPacket;               ///< Maximum size of packet allowed.
  
  pthread_mutex_t mutex;              ///< Mutex for locking access to this struct

  volatile int execute;               ///< If execute != 0, module is active.

  int authMode;                       ///< Current authMode; 0 = no auth, 1 = h2hauth, 2 = h2h+client auth

  // For tracking Async queries
  //TMsgReplyBuffer msgReplyBuffer; ///< message replybuffer for processing async messages
  //uint32_t msgReplyBufferSequence; ///< Message sequence to be used for this GIMnetAPs initiated communication.
 
} TConnectionDisp;


/** Intialize ConnectionDisp module.
 */
int connectionDispInit(TConnectionDisp *cd, TConnectionList *cl);


/** Deinitialize ConnectionDisp module.
 */
int connectionDispDeinit(TConnectionDisp *cd);


/** Add new listening port for TCP.
 *
 */
int connectionDispAddServerTCP(TConnectionDisp *cd, int aPort, const char *localaddr);


/** Add new client target hub using TCP.
 *
 */
int connectionDispAddClientTCP(TConnectionDisp *cd, const char *aAddr, int aPort);


/** Initialize sockets.
 *
 */
int connectionDispInitializeSockets(TConnectionDisp *cd);


/** Execute connectionDisp. This function returns when app is about to
 * terminate.
 */
int connectionDispExecute(TConnectionDisp *cd);

/** Process timer event.
 *
 * This function should be called to process events connected to time
 * (For example; Initiating re-connections of lost connections)
 */
void connectionDispProcessTimerEvent(TConnectionDisp *cd);

/** Terminate connectionDisp.
 *
 */
int connectionDispTerminate(TConnectionDisp *cd);
//////////////////////////// OLD
//////////////////////////// OLD
//////////////////////////// OLD
//////////////////////////// OLD
//////////////////////////// OLD
//////////////////////////// OLD
//////////////////////////// OLD
//////////////////////////// OLD
//////////////////////////// OLD
//////////////////////////// OLD

#if 0
int connectionDispSetFlags(TConnectionDisp *cd, unsigned int flags);
int connectionDispSetTCPPort(TConnectionDisp *cd, int client_port);
int connectionDispSetUDPPort(TConnectionDisp *cd, int client_port);
int connectionDispSetUNIXSocketFile(TConnectionDisp *cd, const char *socketfile);

int connectionDispAddAP2AP(TConnectionDisp *cd, const char *hub_addr, int hub_port);
int connectionDispSetAP2APLinkDelay(TConnectionDisp *cd, const int link_id, const int delay_ms);

int connectionDispSetMaxPacket(TConnectionDisp *cd, int maxsize);
int connectionDispSetHubID(TConnectionDisp *cd, int hubID);
int connectionDispSetDefaultRoute(TConnectionDisp *cd, int hubID);
int connectionDispSetMasterHub(TConnectionDisp *cd, int masterID);
int connectionDispAddRoute(TConnectionDisp *cd, int targetID, int gatewayID);
int connectionDispExecute(TConnectionDisp *cd);
int connectionDispWaitDispatcher(TConnectionDisp *cd);

int connectionSetProtocol(TConnectionDisp *cd); //FIXME;
#endif //0

#endif // _CONNECTIONDISP_H_
